/**
 * Extend Array.unique
 */
Array.prototype.unique = function() {
	var a = [];
    var l = this.length;
    for(var i=0; i<l; i++) {
    	for(var j=i+1; j<l; j++) {
        // If this[i] is found later in the array
        	if (this[i] === this[j])
			j = ++i;
		}
		a.push(this[i]);
    }
    return a;
};



var MyClassifier = function() {
	////////////////////////////////////
	// open database
	// DB name, version, display name, size(bytes order)
	this.db = openDatabase("naivebayse", "", "Naive Bayse", 2*1024*1024);

	/////////////////////////////////////
	// create table
	/////////////////////////////////////
	this.db.transaction(function(tx) {
		tx.executeSql("create table if not exists frequency ( \
			word varchar(64) unique, \
			like integer default 0, \
			dislike integer default 0, \
			lastupdate timestamp with timezone not null, \
			constraint frequency_pkey primary key (word));");
	});
};

MyClassifier.prototype = {
	db : null, // Database property
	
	/**
	 * increment like's frequency field. This method also updates lastupdate field.
	 *
	 * @parameter word ( indicates word column. )
	 */
	like : function(sentence) {
		var words = this.getWords(sentence);
		for ( var i = 0; i < words.length; i++) {
			this.incrementLike(words[i]);
		}
	},
	
	incrementLike : function(word) {
		this.db.transaction(function(tx) {
			var _sql = "insert into frequency (word, like, lastupdate) values ('"+word+"', 1, datetime('now', 'localtime'));";
			tx.executeSql(_sql, // sql (insert)
				[], // parameter
				function(tx, rx){}, // onSuccess
				function(tx, e) { // onError (update)
					var __sql = "update frequency set like = like + 1, lastupdate = datetime('now', 'localtime') where word = '"+word+"';";
					tx.executeSql(__sql);
				}
			);
		});
	},
	
	/**
	 * increment dislike's frequency field. This method also updates lastupdate field.
	 *
	 * @parameter word ( indicates word column. )
	 */
	dislike : function(sentence) {
		var words = this.getWords(sentence);
		for(var i = 0; i < words.length; i++) {
			this.incrementDisLike(words[i]);
		}
	},

	incrementDisLike : function(word) {
		this.db.transaction(function(tx) {
			var _sql = "insert into frequency (word, dislike, lastupdate) values ('"+word+"', 1, datetime('now', 'localtime'));";
			tx.executeSql(_sql, // sql (insert)
				[], // parameter
				function(tx, rx){}, // onSuccess
				function(tx, e) { // onError (update)
					var __sql = "update frequency set dislike = dislike + 1, lastupdate = datetime('now', 'localtime') where word = '"+word+"';";
					tx.executeSql(__sql);
				}
			);
		});
	},
	
	classify : function(sentence, id, callback) {
		var ret = 0;
		var flag = true;
		var words = this.getWords(sentence);

		var cond = '';
		for(var i = 0; i < words.length; i++) {
			cond += (i == 0 ? '': ", ");
			cond += "'"+words[i]+"'";
		}
		var sql = "select word, like, dislike from frequency where word in ("+cond+");";
//		alert(sql);
		this.db.transaction(function(tx) {
			tx.executeSql(sql,
				[],
				function(tx, rx){
					var like = 0, dislike = 0;
					var rows = rx.rows;
					for(var i = 0; i < rows.length; i++) {
						lp = (rows.item(i).like == 0 ? 0.001 : rows.item(i).like);
						dlp = (rows.item(i).dislike == 0 ? 0.001 : rows.item(i).dislike);
						if(rows.item(i).word.substr(0,1) == '#') {
							lp *= 10;
							dlp *= 10;
						}
						like += Math.log(lp);
						dislike += Math.log(dlp);
					}
					//alert(like+", "+dislike);
					ret = like - dislike;
					callback(id, ret);
				},
				function(tx, e) {
					ret = 0;
				}
			);
		});
	},
	
	getWords : function(text) {
		text = text.replace(/(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/, '');
		var arr = [];
		text = text.replace(/(\w+)/g, ' $1 ');
		
		var _arr = text.split(/[\s,.'!?\-_！。．、，？！()（）]+/);
		
		
		for(var i = 0; i < _arr.length; i++) {
			if(_arr[i].match(/^\w+$/)) {
				arr.push(_arr[i]);
			} else {
				for(var j = 0; j < _arr[i].length; j += 2) {
					arr.push(_arr[i].substr(j, 2));
				}
			}
		}
		arr = arr.unique();
		
		return arr;
	}
};
